/**
 * 该场景非固定长宽:
 *   长 200 以上即可
 *   宽 200 以上即可
 * 
 * HTML 设置方案
 * #main
 *   #ribbons (Ribbons 的 root element)
 */

import { Arcade, Panel,
		PHASE_NO_READY, PHASE_SEND_DANMU, PHASE_BEGIN_LOTTERY, PHASE_FINISH_LOTTERY } from '../comps/arcadePanel';

function createScene(context) {
	let t = new App(context);
	let scene = new context.Scene({
		require : ['zrender'],
		init : (libs) => t.init(libs),
		destroy : () => t.destroy(),
		collectInfo : () => t.collectInfo(),
		onMessage : (key, data) => t.onMessage(key, data),
		onTick : (assetId, data) => t.onTick(assetId, data),
	});
	t.sendStatus = scene.sendStatus;
	return scene;
}

class App {
  roomId = 0;
  danmaku = null;

  // dom
  /** @type {Panel} */
  panel = null;
  /** @type {Arcade} */
  arcade = null;

  constructor(context) {
    this.context = context;

    global.app = this;
  }

  init(libs) {
    // 先要创建 Dom
    const main = document.getElementById('main');
    const div = document.createElement('div');
    div.id = 'zrender';
    div.style.position = 'absolute';
    div.style.overflow = 'hidden';
    div.style.width = '1280px';
    div.style.height = '720px';
    div.style.left = '0px';
    div.style.top = '0px';
    main.appendChild(div);
    const zr = libs.zrender.init(div);

    const top = document.createElement("canvas");
    top.id = 'top';
    top.style.width = '1280px';
    top.style.height = '720px';
    top.style.position = 'absolute';
    top.style.left = '0px';
    top.style.top = '0px';
    top.style.zIndex = 10;
    top.style.mixBlendMode = 'screen';
    main.appendChild(top);

    this.panel = new Panel({
      zrender : libs.zrender,
      zr, top,
      context : this.context,
      danmaku : this.danmaku
    });
    
    this.arcade = new Arcade({
      panel : this.panel
    });
    this.panel.arcade = this.arcade;
    this.panel.init();
    this.panel.setWords(this.arcade.words);
    this.panel.onAnimationFinished = (p) => this.sendStatus();

		const roomStr = this.context.parseInitParam().room;
		if (roomStr) {
			const roomId = parseInt(roomStr);
			if (roomId) {
				this.handleAsset(roomId);
			}
		}

    requestAnimationFrame(this.tick.bind(this));
  }

  destroy() {
    if (this.panel) {
      this.panel.destroy();
    }

    let content = document.getElementById('canvas');
    if (content) {
      content.remove();
    }
    content = document.getElementById('div');
    if (content) {
      content.remove();
    }
  }
  
  collectInfo() {
    return {
      roomId : this.roomId,
      phase : this.arcade.phase,
      words : this.arcade.words,
      rules : this.arcade.rules.map( r => r.collectInfo() ),
      customers : this.arcade.participants.map( c => c.collectInfo() ),
      strategy : this.arcade.strategy,
    };
  }

  tick() {
    this.arcade.tick();
    this.panel.tick();
    requestAnimationFrame(this.tick.bind(this));
  }
  
  /**
   * room - 告诉你房间号
   * rules - 告诉你规则
   * 
   * reset - 结束抽奖, 所有抽奖历史数据、用户现有分数都重置 (慎用)
   * begin - 启动抽奖的发弹幕阶段. 可以设置倒计时、口令.
   * ready - 抽奖的发弹幕阶段结束
   * lottery - 抽奖中. 可以选择一次抽出多少人, 还是淘汰多少人, 还是到哪个抽奖阶段
   */
  onMessage(key, data) {
    switch (key) {
      case 'room': { // monitor 告诉你房间号
        this.handleAsset(data.roomId);
        this.sendStatus();
      } return;
      case 'words': {
        this.arcade.setWords(data.words);
        this.sendStatus();
      } return;
      case 'rules': {
        // TODO 设置规则
        this.sendStatus();
      } return;
      case 'reset': {
        this.arcade.reset();
        this.sendStatus();
      } return;
      case 'begin': {
        this.arcade.begin(data);
        this.sendStatus();
      } return;
      case 'ready': {
        this.arcade.ready();
        this.sendStatus();
      } return;
      case 'lottery': {
        if (this.arcade.phase == PHASE_SEND_DANMU || this.arcade.phase == PHASE_NO_READY || this.arcade.phase == PHASE_BEGIN_LOTTERY) {
          return; // 不准抽
        }
        this.arcade.phase = PHASE_BEGIN_LOTTERY; // 动画结束后就是 PHASE_FINISH_LOTTERY
        let remain = data.remain == null ? 1 : data.remain < 1 ? 1 : data.remain;
        let strategy = data.strategy;
        this.arcade.startLottery(remain, strategy);
        this.sendStatus();
        setTimeout(() => {
          this.arcade.doLottery(remain);
          this.arcade.phase = PHASE_FINISH_LOTTERY;
          this.sendStatus();
        }, 500);
      } return;
    }
    
    console.log("danmaku/danmaku_arcade 收到无法解析的命令: ", key, data);
  }

  sendStatus() {} // 等待被覆盖

  onTick(assetId, data) {
    if (this.danmaku != null) {
      this.danmaku.filterAssetTick(assetId, data);
    }
  }

  /**
   * 创建资源、绑定资源
	 * @param {number} roomId B 站房间号, 例如 7734200
   */
  handleAsset(roomId) {
    this.roomId = roomId;

    this.danmaku = new this.context.Danmaku(roomId);
    this.danmaku.createSource()
      .then(() => this.danmaku.openSource())
      .then(() => {
        this.danmaku.onDanmuReceived = (o) => this.arcade.onDanmuReceived(o);
        this.danmaku.onGiftReceived = (o) => this.arcade.onGiftReceived(o);
        this.arcade.upUId = this.danmaku.uid;
      });
  }
}

export default createScene;